package com.sec.etech.org.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sec.etech.org.dao.OrgRelationMapper;
import com.sec.etech.redis.RedisUtil;
import org.openbpm.base.api.exception.BusinessMessage;
import org.openbpm.base.core.id.IdUtil;
import org.openbpm.org.core.constant.RelationTypeConstant;
import org.openbpm.org.core.manager.OrgRelationManager;
import org.openbpm.org.core.manager.RoleManager;
import org.openbpm.org.core.manager.impl.OrgRelationManagerImpl;
import org.openbpm.org.core.model.OrgRelation;
import org.openbpm.org.core.model.Role;
import org.openbpm.sys.util.ContextUtil;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@Primary
@Service("etechrelationservice")
public class EtechRelationService extends OrgRelationManagerImpl implements OrgRelationManager {

    @Resource
    RoleManager roleManager;
    @Resource
    EtechGroupService etechGroupService;
    @Resource
    JdbcTemplate jdbcTemplate;
    @Resource
    EtechUserService etechUserService;
    @Resource
    RedisUtil redisUtil;
    @Resource
    OrgRelationMapper orgRelationMapper;

    /**
     * 从部门班组配置中同步主管内勤助理角色人员
     *
     * @param roleNames
     */
    @Transactional(rollbackFor = Exception.class)
    public void syncRole(String roleNames) {
        if (StrUtil.isBlank(roleNames)) {
            return;
        }
        //删除缓存
        Set<String> keys = redisUtil.keys("current*Ids*");
        if (CollUtil.isNotEmpty(keys)) {
            redisUtil.del(keys);
        }

        String[] names = roleNames.split(",");
        for (String name : names) {
            Role role = roleManager.getByAlias(name);
            if (role != null) {
                if (!"manager".equals(name) && !"assistant".equals(name) && !"inter".equals(name)) {
                    continue;
                }
                //排除掉已取消组织下的部门
                List<String> notGroupIds = etechGroupService.getAllDprtIdsByDprtId("422166904457920513");
                List<String> uids = CollUtil.newArrayList();
                StringBuffer sql = new StringBuffer("select uid from wss_dprt_{} where active = 1");
                if (CollUtil.isNotEmpty(notGroupIds)) {
                    sql.append(" and dprtid not in(");
                    sql.append(StrUtil.join(",", notGroupIds));
                    sql.append(")");
                }
                List<Map<String, Object>> list = jdbcTemplate.queryForList(StrUtil.format(sql.toString(), name));
                if (CollUtil.isNotEmpty(list)) {
                    for (Map<String, Object> stringObjectMap : list) {
                        uids.add(stringObjectMap.get("uid").toString());
                    }
                }
                String delSql = "delete t1 from org_relation t1 \n" +
                        "left join org_role t2 on t1.role_id_ = t2.id_\n" +
                        "where t1.type_='{}' and t2.id_ = '{}' ";
                if (CollUtil.isNotEmpty(uids)) {
                    delSql += StrUtil.format("and t1.user_id_ not in ({})", StrUtil.join(",", uids));
                }
                jdbcTemplate.update(StrUtil.format(delSql, RelationTypeConstant.USER_ROLE.getKey(), role.getId(), StrUtil.join(",", uids)));

                List<String> oldUids = etechUserService.getUserIdsByRoleCode(name);
                for (String uid : uids) {
                    if (!CollUtil.contains(oldUids, uid)) {
                        OrgRelation orgRelation = new OrgRelation();
                        orgRelation.setId(IdUtil.getSuid());
                        orgRelation.setUserId(uid);
                        orgRelation.setRoleId(role.getId());
                        orgRelation.setType(RelationTypeConstant.USER_ROLE.getKey());
                        orgRelation.setCreateTime(new Date());
                        orgRelation.setCreateBy(ContextUtil.getCurrentUserId());
                        orgRelation.setUpdateTime(new Date());
                        orgRelation.setUpdateBy(ContextUtil.getCurrentUserId());
                        this.create(orgRelation);
                    }
                }
            }
        }
    }


    public void removeUserGroup(List<String> userIds) {
        jdbcTemplate.execute("delete from org_relation where user_id_ in(" + CollUtil.join(userIds, ",") + ") and type_ = 'groupUser'");
    }

    public boolean checkActiveUsers(String groupId) {
        Integer i = jdbcTemplate.queryForObject("select sum(ou.status_) from org_relation a\n" +
                "    left join org_user ou on a.user_id_ = ou.id_\n" +
                "where type_ = 'groupUser' and group_id_ = ?", new Object[]{groupId}, Integer.class);
        if (i == null || i.equals(0)) {
            return true;
        } else {
            return false;
        }
    }

    public void deleteGroup(String groupId) {
        // 递归作废下层组织
        List<String> groupIds = etechGroupService.getSubDprtIds(groupId);
        for (String id : groupIds) {
            deleteGroup(id);
        }

        if (checkActiveUsers(groupId)) {
            jdbcTemplate.update("update org_group set name_ = concat(name_,'(已作废)'), active = 0 where id_ = ?", groupId);
        } else {
            throw new IllegalArgumentException("组织下还有可用用户，请先调整组织下人员");
        }
    }

    /**
     * 获取单条信息
     *
     * @param id
     * @return
     */
    public com.sec.etech.org.model.OrgRelation getDataById(String id) {
        return this.orgRelationMapper.getDataById(id);
    }

    /**
     * 编辑备注
     *
     * @param orgRelation
     * @return
     */
    public boolean editRemark(com.sec.etech.org.model.OrgRelation orgRelation) {
        if (orgRelation != null || orgRelation.getId() != null) {
            String remark = StrUtil.isBlank(orgRelation.getRemark()) ? null : orgRelation.getRemark();
            this.orgRelationMapper.update(null, Wrappers.<com.sec.etech.org.model.OrgRelation>lambdaUpdate()
                    .eq(com.sec.etech.org.model.OrgRelation::getId, orgRelation.getId())
                    .set(com.sec.etech.org.model.OrgRelation::getRemark, remark)
                    .set(com.sec.etech.org.model.OrgRelation::getUpdateBy, ContextUtil.getCurrentUserId())
                    .set(com.sec.etech.org.model.OrgRelation::getUpdateTime, new Date())
            );
        } else {
            throw new BusinessMessage("数据不存在或者已删除！");
        }
        return false;
    }

    /**
     * 导出角色下的用户
     * @param roleId
     * @param fullname
     * @param response
     * @throws IOException
     */
    public void exportList(String roleId, String fullname, HttpServletResponse response) throws IOException {
        Role role = roleManager.get(roleId);
        if (role == null) {
            throw new BusinessMessage("角色不存在或者已删除,id=" + roleId);
        }
        String relationType = RelationTypeConstant.USER_ROLE.getKey();
        if(StrUtil.isBlank(fullname)){
            fullname = null;
        }
        List<com.sec.etech.org.model.OrgRelation> list = this.orgRelationMapper.queryList(roleId, relationType, fullname);
        List<Map<String, Object>> rows = CollUtil.newLinkedList();
        for (com.sec.etech.org.model.OrgRelation orgRelation : list) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("用户名", orgRelation.getUserName());
            map.put("账号", orgRelation.getUserAccount());
            map.put("部门", orgRelation.getUserDprtname());
            map.put("备注", orgRelation.getRemark());
            map.put("角色名", orgRelation.getRoleName());
            map.put("操作时间", orgRelation.getUpdateTime());
            rows.add(map);
        }
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(rows, true);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = StrUtil.format("角色【{}】下用户列表", role.getName());
        response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

}
